/**
* 
*	AuthoController类
*	作者：邓磊
*	时间：2016年7月4日 16:40:43
*	作用：微信授权
*	域：/weixin/user
*
*/
package com.eptok.weixin.action;


import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.hibernate.envers.tools.StringTools;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.eptok.weixin.util.WxCooikeManager;

import hikefa.core.global.GlobalCache;
import hikefa.core.remote.client.RemoteCall;
import net.sf.json.JSONObject;
import yspay.express.store.WeiXinApi;
import yspay.express.store.WxConstant;
import yspay.express.store.WxStore;
import yspay.express.util.CommonUtil;
import yspos.cpfs.express.entity.ExpUserinfo;
import yspos.cpfs.express.entity.ExpWebchatUserinfo;
import yspos.cpfs.remoteserver.iface.IExpressService;

@Controller
public class AuthoController  extends BaseDispatchAction{
	private static final Logger log = Logger.getLogger(AuthoController.class);
	private IExpressService expressServer = (IExpressService) RemoteCall.getRemoteObject(IExpressService.class);
	private static String lastCode = "";
	/*授权地址*/
	private static String aotho_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=#APPID&redirect_uri=REDIRECTURI&response_type=code&scope=snsapi_userinfo&state=#STATE#wechat_redirect";
	
	
	@RequestMapping(value = { "/toAutho.do" })    
	public String doGet(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
		log.info("授权开始====================================");
		String url = aotho_url;
		url= url.replace("#APPID",WxStore.getAppid());
		String redictUrl = GlobalCache.getSystemCache("gzh_interface_url_aothordc");//授权回调地址
		redictUrl += "?redirecturl="+getBaseUrl(request)+"/getUserInfo.do";
		redictUrl = URLEncoder.encode(redictUrl,"UTF-8");
		url = url.replace("REDIRECTURI",redictUrl);
		url = url.replace("#STATE","1");
		log.info("授权地址："+url);
		return "redirect:"+url;
	}
	
	/**
	 * 获取用户，更新数据
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = { "/getUserInfo.do" })    
	public Object switchEvn(HttpServletRequest request, HttpServletResponse response,String code) throws UnsupportedEncodingException {
		//去重
		log.info("收到code的回调,code:"+code);
		if(null != lastCode && lastCode.equals(code))
		{
			log.info("授权重复");
			return null;
		}
		try {
			lastCode = code;
			String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+WxStore.getAppid()+"&secret="+WxStore.getAppsecret()+"&code="+code+"&grant_type=authorization_code";
			log.info("授权请求的URL:"+url);
			JSONObject jsonRet = CommonUtil.httpsRequest(url, CommonUtil.REQ_GET, null);
			//log.info("通过code换取的票据信息："+jsonRet);
			if(!jsonRet.containsKey("openid"))
			{
				log.info("授权结束：失败(微信接口获取用户信息失败)====================================");
				return toFail(request,"1", "授权失败！");
			}
			String openid = jsonRet.getString("openid");
			
			//获取用户信息
			String url2 = WxConstant.USER_GETBYID_URL.
					replace("ACCESS_TOKEN", jsonRet.getString("access_token")).
					replace("OPENID", openid);
			JSONObject jsonRet2 = CommonUtil.httpsRequest(url2, CommonUtil.REQ_GET, null);
			log.info("获取的用户信息JSON:"+jsonRet);
			if(jsonRet2 == null)
			{
				log.info("授权结束：失败====================================");
				return toFail(request,"1", "从微信获取用户信息失败！");
			}
			
			ExpWebchatUserinfo wxUser = null;
			ExpUserinfo user = null;
		
			
			wxUser = expressServer.webchatUserinfoLoad(openid);
			if(wxUser == null)
			{
				log.info("正在同步更新用户信息");
				wxUser = syncUser(request,jsonRet2);
				if(wxUser == null)
				{
					return toFail(request, "1", "保存用户信息失败，请联系管理员");
				}
			}else
			{
				log.info("正在异步更新用户信息");
				asyncUser(request,jsonRet2,response);
			}
			user = expressServer.userinfoGetByopid(jsonRet2.getString("openid"));
			WxCooikeManager.setUser(response, user);
			WxCooikeManager.setWxUser(response, wxUser);
			
		} catch (Exception e) {
			log.info("授权结束：失败====================================");
			return toFail(request,"1", "本地获取用户信息失败！"+e.getMessage());
		}
		String lastUrl =WxCooikeManager.getCookieValue("lastUrl", request);
		if(StringTools.isEmpty(lastUrl))
		{
			lastUrl = request.getServerName()+"/index.do";
		}else
		{
			lastUrl = URLDecoder.decode(lastUrl,"UTF-8");
		}
		log.info("授权结束：成功====================================");
		return "redirect:"+lastUrl;
	}
	
	/**
	 * 异步更新用户信息
	 * 为了增加体验 如果有威信用户数据就异步更新否则就同步更新 
	 */
	@Async
	public void asyncUser(HttpServletRequest request,JSONObject aothoRet,HttpServletResponse response)
	{
		ExpWebchatUserinfo wxUser = syncUser(request, aothoRet);
		WxCooikeManager.setWxUser(response, wxUser);
	}
	
	/**
	 * 同步更新微信用户数据
	 */
	public ExpWebchatUserinfo syncUser(HttpServletRequest request,JSONObject aothoRet)
	{
		//找到这条信息
		ExpWebchatUserinfo user = null;
		String openid = aothoRet.getString("openid");
		
		try {
			user = expressServer.webchatUserinfoLoad(openid);
			if(user == null)//第一次插入数据
			{
				user = new ExpWebchatUserinfo();
				JSONObject userJson = WeiXinApi.getUserByopenid(openid);
				if(userJson.getString("subscribe").equals("1"))//关注  有数据
				{
					user.setCity(userJson.getString("city"));
					user.setCountry(userJson.getString("country"));
					user.setHeadimgUrl(userJson.getString("headimgurl"));
					user.setLanguage(userJson.getString("language"));
					user.setNickname(userJson.getString("nickname"));
					user.setOpenId(userJson.getString("openid"));
					user.setOriginal("");
					user.setProvince(userJson.getString("province"));
					user.setSex(userJson.getString("sex"));
					user.setSubscribeTm(new Date(userJson.getLong("subscribe_time")*1000L));
					user.setState("1");
					user.setUnSubscribeTm(null);
				}else
				{
					user.setCity(aothoRet.getString("city"));
					user.setCountry(aothoRet.getString("country"));
					user.setHeadimgUrl(aothoRet.getString("headimgurl"));
					user.setLanguage(aothoRet.getString("language"));
					user.setNickname(aothoRet.getString("nickname"));
					user.setOpenId(aothoRet.getString("openid"));
					user.setOriginal("");
					user.setProvince(aothoRet.getString("province"));
					user.setSex(aothoRet.getString("sex"));
					user.setSubscribeTm(new Date());
					user.setUnSubscribeTm(new Date());
					user.setState("0");
				}
				expressServer.webchatUserinfoSave(user);
			}else//已有数据 更新
			{
				if(!isToday(user.getUpdateTm()))
				{
					JSONObject userJson = WeiXinApi.getUserByopenid(openid);
					if(userJson.getString("subscribe").equals("1"))
					{
						user.setState("1");//已经关注
						user.setCity(userJson.getString("city"));
						user.setCountry(userJson.getString("country"));
						user.setHeadimgUrl(userJson.getString("headimgurl"));
						user.setLanguage(userJson.getString("language"));
						user.setNickname(userJson.getString("nickname"));
						user.setOpenId(userJson.getString("openid"));
						user.setProvince(userJson.getString("province"));
						user.setSex(userJson.getString("sex"));
						user.setSubscribeTm(new Date(userJson.getLong("subscribe_time")*1000L));
						user.setUnSubscribeTm(null);
					}else
					{
						user.setState("0");//未关注
						user.setCity(aothoRet.getString("city"));
						user.setCountry(aothoRet.getString("country"));
						user.setHeadimgUrl(aothoRet.getString("headimgurl"));
						user.setLanguage(aothoRet.getString("language"));
						user.setNickname(aothoRet.getString("nickname"));
						user.setOpenId(aothoRet.getString("openid"));
						user.setProvince(aothoRet.getString("province"));
						user.setSex(aothoRet.getString("sex"));
						user.setUnSubscribeTm(new Date());
					}
					expressServer.webchatUserinfoUpdate(user);
				}
			}
			log.info("sync WebchatUserinfo success !! ");
			user = expressServer.webchatUserinfoLoad(openid);
			return user;
		} catch (Exception e) {
			log.error("sync WebchatUserinfo error："+e.getMessage());
			return null;
		}
	}
	
	/**
	 * 
	 * 请使用微信浏览器打开
	 */
	@RequestMapping(value = { "/toBrowserError.do" })    
	public Object toWxBrowser(HttpServletRequest request, HttpServletResponse response) throws Exception {
		return toFail(request, "1", "请使用微信浏览器打开");
	}
	

	/*
	 * 清理缓存,即退出登陆
	 */
	@RequestMapping(value = { "/logOut.do" })    
	public ModelAndView logOut(HttpServletRequest request, HttpServletResponse response) 
	{
		try {
			
			if(null != WxCooikeManager.getCookie(WxConstant.USER_SESSION, request)) WxCooikeManager.clearCookie(WxConstant.USER_SESSION, request, response);
			if(null != WxCooikeManager.getCookie(WxConstant.USER_WX_SESSION, request)) WxCooikeManager.clearCookie(WxConstant.USER_WX_SESSION, request, response);
			
			if(null != WxCooikeManager.getCookie("order.jjdzId", request)) WxCooikeManager.clearCookie("order.jjdzId", request, response);
			if(null != WxCooikeManager.getCookie("order.sjdzId", request)) WxCooikeManager.clearCookie("order.sjdzId", request, response);
			if(null != WxCooikeManager.getCookie("order.operId", request)) WxCooikeManager.clearCookie("order.operId", request, response);
			if(null != WxCooikeManager.getCookie("order.expType", request)) WxCooikeManager.clearCookie("order.expType", request, response);
			if(null != WxCooikeManager.getCookie("order.ensurePrice", request)) WxCooikeManager.clearCookie("order.ensurePrice", request, response);
			if(null != WxCooikeManager.getCookie("order.weight", request)) WxCooikeManager.clearCookie("order.weight", request, response);
			if(null != WxCooikeManager.getCookie("order.wp", request)) WxCooikeManager.clearCookie("order.wp", request, response);
			
			if(null != WxCooikeManager.getCookie("point.lat", request)) WxCooikeManager.clearCookie("point.lat", request, response);
			if(null != WxCooikeManager.getCookie("point.lng", request)) WxCooikeManager.clearCookie("point.lng", request, response);
			
			return toSuccess(request, "0", "清除缓存成功");
		} catch (Throwable e) {
			e.printStackTrace();
			return toFail(request, "1", "清除缓存失败："+e.getMessage());
		}
		
	}
	
	public boolean isToday(Date update)
	{
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		return df.format(update).equals(df.format(new Date()));
	}
}
